package com.hmsm.sys.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.hmsm.server.base.BaseService;
import com.hmsm.server.common.AppContextService;
import com.hmsm.sys.dao.UserOrgDao;
import com.hmsm.sys.po.DeptInfo;
import com.hmsm.sys.po.OrgInfo;
import com.hmsm.sys.po.RoleInfo;
import com.hmsm.sys.po.UserInfo;
import com.hmsm.sys.po.UserOrg;
/**
 * 组织机构用户关联信息
 * 
 * @author 舒俊
 *
 *@version 1.0, 2012-11-29 下午02:20:22
 */
@Component
public class UserOrgService extends BaseService<UserOrg, Integer, UserInfo, RoleInfo> {

	public UserOrgDao getUserOrgDao() {
		return (UserOrgDao) baseDao;
	}

	@Resource
	public void setUserOrgDao(UserOrgDao userOrgDao) {
		baseDao = userOrgDao;
	}

	private DeptInfoService getDeptInfoService(){
		return AppContextService.getDeptInfoService();
	}
	
	/**
	 * 保存用户机构关联信息
	 * @param userId
	 * @param orgId
	 * @param deptId
	 * @author 舒俊
	 */
	public void save(int userId,int orgId, int orderNum,int deptId){
		UserOrg userOrg = new UserOrg();
		userOrg.setUserId(userId);
		userOrg.setOrgId(orgId);
		userOrg.setOrderNum(orderNum);
		userOrg.setDeptId(deptId);
		userOrg.setState(1);
		List<UserOrg> list = getUserOrgDeptsByUserId(userId, orgId);
		int order = 0;
		for(UserOrg userOrg1:list){
			if(userOrg1.getOrderNum()!=order++){
				userOrg1.setOrderNum(order);
				getUserOrgDao().update(userOrg1);
			}
		}
		userOrg.setOrderNum(order++);
		getUserOrgDao().save(userOrg);
	}
	
	/**
	 * 根据部门ID获取关联信息
	 * @param deptId
	 * @return
	 * @author 何杰 2013-2-21
	 */
	public List<UserOrg> getUserOrgListByDeptId(int deptId){
		UserOrg uo = new UserOrg();
		uo.setDeptId(deptId);
		uo.setState(1);
		return getUserOrgDao().query(uo);
	}
	
	/**
	 * 根据用户ID获取用户和机构的关联信息
	 * @param userId
	 * @return
	 * @author 何杰 2013-3-13
	 */
	public UserOrg getUserOrgByUserId(int userId, Integer orgId){
		List<UserOrg> all = getUserOrgDeptsByUserId(userId, orgId);
		if(all.size()>0){
			return all.get(0);
		}else{
			return null;
		}
	}

	public List<UserOrg> getUserOrgDeptsByUserId(int userId, Integer orgId) {
		List<UserOrg> list = null;
		
		UserOrg userOrg = new UserOrg();
		userOrg.setUserId(userId);
		userOrg.setOrgId(orgId);
		userOrg.setState(1);
		list = getUserOrgDao().query(userOrg, "orgId,orderNum");
		
		return list;
	}
	
	/**
	 * 根据用户ID获取用户和机构的关联信息
	 * @param userId
	 * @return
	 * @author 何杰 2013-3-13
	 */
	public List<OrgInfo> getUserOrgsByUserId(int userId){
		List<OrgInfo> list = null;

		Map<Integer, OrgInfo> orgMap = new HashMap<Integer, OrgInfo>();
		
		List<UserOrg> all = getUserOrgDeptsByUserId(userId, null);
		for(UserOrg userOrg:all){
			if(userOrg.getOrgId()!=null&&userOrg.getOrgId()>0){
				if (!orgMap.containsKey(userOrg.getOrgId())){
					OrgInfo org = getDeptInfoService().getOrgInfoById(userOrg.getOrgId());
					if (org!=null){
						orgMap.put(org.getPkId(), org);
					}
				}
			}
		}
		list = new ArrayList<OrgInfo>(orgMap.values());
		
		Collections.sort(list, new Comparator<OrgInfo>(){

			@Override
			public int compare(OrgInfo o1, OrgInfo o2) {
				return o1.getPkId()-o2.getPkId();
			}
			
		});
		
		return list;
	}

	public DeptInfo getUserDepart(Integer userId) {
		DeptInfo userDepart = null;
		
		UserOrg userOrg = getUserOrgByUserId(userId, null);
		if (userOrg!=null){
			userDepart = getDeptInfoService().getById(userOrg.getDeptId());
		}
		
		return userDepart;
	}

	/**
	 * 更新用户部门
	 * @param userInfoPo
	 * @throws Exception
	 */
	public void setUserDepart(UserInfo userInfoPo) throws Exception {
		UserOrg userOrg = this.getUserOrgByUserId(userInfoPo.getPkId(), null);
		if (userOrg==null){
			userOrg= new UserOrg();
			userOrg.setUserId(userInfoPo.getPkId());
			DeptInfo userDept = null;
			if (userInfoPo.getDepart()!=null){
				userDept = getDeptInfoService().getById(userInfoPo.getDepart().getPkId());
			}
			if (userDept==null){
				userOrg.setDeptId(0);
				userOrg.setOrgId(0);
				userOrg.setState(1);
			}else{
				userOrg.setDeptId(userDept.getPkId());
				userOrg.setOrgId(userDept.getOrgId());
				userOrg.setState(1);
				baseDao.save(userOrg);
			}
		}else{
			if (userInfoPo.getDepart()==null){
				userOrg.setDeptId(0);
				userOrg.setOrgId(0);
				userOrg.setState(1);
			}else{
				userOrg.setDeptId(userInfoPo.getDepart().getPkId());
				userOrg.setOrgId(userInfoPo.getDepart().getOrgId());
			}
			baseDao.update(userOrg);
		}
	}

	/**
	 * 获取指定组织机构下的用户直属部门列表
	 * @param userInfo
	 * @param orgRootId
	 * @return
	 */
	public List<DeptInfo> getUserDepts(UserInfo userInfo) {
		return getUserDepts(userInfo, null, 0);
	}

	/**
	 * 获取指定组织机构下的用户直属部门列表
	 * @param userInfo
	 * @param orgRootId
	 * @return
	 */
	public List<DeptInfo> getUserDepts(UserInfo userInfo, Integer deptId, int pattern) {
		return getUserDepts(userInfo, deptId, pattern, null);
	}
	
	public DeptInfo loadById(Integer deptId, Map<Integer, DeptInfo> deptCache) {
		DeptInfo deptInfo = null;
		
		if(deptCache==null) {
			deptCache = new HashMap<Integer, DeptInfo>();
		}
		
		deptInfo = deptCache.get(deptId);
		if(deptInfo==null){
			deptInfo = getDeptInfoService().getById(deptId);
			if(deptInfo!=null){
				deptCache.put(deptId, deptInfo);
				loadParent(deptInfo, deptCache);
			}
		}
		
		return deptInfo;
	}

	private void loadParent(DeptInfo deptInfo, Map<Integer, DeptInfo> deptCache) {
		if(deptInfo!=null&&deptInfo.getPkId()!=null&&deptInfo.getPkId()!=0&&deptInfo.getParId()!=null) {
			DeptInfo parent = loadById(deptInfo.getParId(), deptCache);
			if(parent!=null) {
				deptInfo.setParent(parent);
				if(parent.getSubDepts()==null) {
					parent.setSubDepts(new ArrayList<DeptInfo>());
				}
				parent.getSubDepts().add(deptInfo);
			}
		}
	}

	/**
	 * 获取指定组织机构下的用户直属部门列表
	 * @param userInfo
	 * @param orgRootId
	 * @return
	 */
	public List<DeptInfo> getUserDepts(UserInfo userInfo, Integer orgRootId, int pattern, Map<Integer, DeptInfo> deptCache) {
		List<DeptInfo> userDepts = new ArrayList<DeptInfo>();
		
		if(deptCache==null) {
			deptCache = new HashMap<Integer, DeptInfo>();
		}
		
		Integer orgId = null;
		if(orgRootId!=null){
			DeptInfo orgRootDept = loadById(orgRootId, deptCache);
			if(orgRootDept!=null){
				orgId = orgRootDept.getOrgId();
			}
		}
		
		List<UserOrg> list = getUserOrgDeptsByUserId(userInfo.getPkId(), orgId);
		List<DeptInfo> userDeptSet = userInfo.getUserDepts();
		if(userDeptSet == null){
			userDeptSet = new ArrayList<DeptInfo>();
			userInfo.setUserDepts(userDeptSet);
		}else{
			userDeptSet.clear();
		}
		for(UserOrg userOrg:list){
			Integer userDeptId = userOrg.getDeptId();
			DeptInfo userDept = loadById(userDeptId, deptCache);
			if(userDept!=null){
				userInfo.setDepart(userDept);
				userInfo.setUserDept(userDept.getDeptPathName(pattern));
				
				userDepts.add(userDept);
				deptCache.put(userOrg.getDeptId(), userDept);
				userDeptSet.add(userDept);
			}
		}
		
		return userDepts;
	}
	
	public UserOrg update(UserOrg uo) {
		return baseDao.update(uo);
	}

	public void updateUserDepts(UserInfo userInfo) {
		List<UserOrg> removeList = getUserOrgDeptsByUserId(userInfo.getPkId(), null);
		List<DeptInfo> addList = new ArrayList<DeptInfo>();
		Map<Integer, Integer> orderMap = new HashMap<Integer, Integer>();
		for(DeptInfo userDept:userInfo.getUserDepts()){
			Integer index = null;
			UserOrg userOrg = null;
			for(UserOrg uo:removeList){
				if (uo.getDeptId().equals(userDept.getPkId())){
					userOrg = uo;
					orderMap.get(userOrg.getOrgId());
					if(index==null){
						index = 0;
					}
					orderMap.put(userOrg.getOrgId(), index+1);
					break;
				}
			}
			if(userOrg==null){
				DeptInfo depart = getDeptInfoService().getById(userDept.getPkId());
				addList.add(depart);
			}else{
				removeList.remove(userOrg);
			}
		}
		for(UserOrg userOrg:removeList){
			try {
				delete(userOrg);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		for(DeptInfo userDept:addList){
			Integer index = orderMap.get(userDept.getOrgId());
			if(index==null){
				index = 0;
			}
			index = index+1;
			orderMap.put(userDept.getOrgId(), index);
			try {
				save(userInfo.getPkId(), userDept.getOrgId(), index, userDept.getPkId());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
